package main

import (
	"bufio"
	"fmt"
	"io"
	"net"
	"strings"
	"time"
)

// handleConnection 负责与单个客户端进行 TCP 双向通信。
// TCP 是面向流的协议，因此我们使用 bufio.Reader 逐行读取。
func handleConnection(conn net.Conn) {
	defer conn.Close() // 四次挥手中的 FIN 由 Close 触发

	addr := conn.RemoteAddr().String()
	fmt.Printf("[server] new connection from %s\n", addr)

	reader := bufio.NewReader(conn)

	for {
		// 设置读超时，避免客户端异常断开导致协程永久阻塞
		if err := conn.SetReadDeadline(time.Now().Add(90 * time.Second)); err != nil {
			fmt.Println("[server] set read deadline err:", err)
			return
		}

		line, err := reader.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				fmt.Printf("[server] client %s disconnected\n", addr)
			} else {
				fmt.Printf("[server] read error from %s: %v\n", addr, err)
			}
			return
		}

		line = strings.TrimSpace(line)
		fmt.Printf("[server] received %q from %s\n", line, addr)

		// 简单协议：收到 "PING" 则回复 "PONG"
		var reply string
		switch strings.ToUpper(line) {
		case "PING":
			reply = "PONG\n"
		case "TIME":
			reply = time.Now().Format(time.RFC3339) + "\n"
		case "QUIT":
			reply = "BYE\n"
			if _, err := conn.Write([]byte(reply)); err != nil {
				fmt.Printf("[server] write error: %v\n", err)
			}
			fmt.Printf("[server] closing connection with %s\n", addr)
			return
		default:
			reply = "ECHO: " + line + "\n"
		}

		if _, err := conn.Write([]byte(reply)); err != nil {
			fmt.Printf("[server] write error to %s: %v\n", addr, err)
			return
		}
	}
}

func main() {
	// TCP 三次握手发生在 Listen → Accept → Dial 过程中，Go 运行时自动处理 SYN/SYN-ACK/ACK。
	listener, err := net.Listen("tcp", "127.0.0.1:9090")
	if err != nil {
		panic(err)
	}
	defer listener.Close()

	fmt.Println("[server] TCP listening on 127.0.0.1:9090")

	for {
		conn, err := listener.Accept() // 阻塞等待客户端连接
		if err != nil {
			fmt.Println("[server] accept err:", err)
			continue
		}
		go handleConnection(conn) // 每个连接独立 goroutine 处理
	}
}
